fix(tools): stop reporting empty git output as a missing repository - #3291
Open
reacechalmers-lab wants to merge 1 commit into
Open
fix(tools): stop reporting empty git output as a missing repository#3291reacechalmers-lab wants to merge 1 commit into
reacechalmers-lab wants to merge 1 commit into
Conversation
`git_stdout` returned `None` both when git failed and when git succeeded with no output, so every read-only `Git*` tool turned a legitimately empty result into "Ensure the current directory is inside a git repository". A clean `GitDiff`, an empty `GitLog`, and a blame of an empty file all reported a missing repository from inside a perfectly valid one — which reads to an agent as a broken environment rather than as "no changes", and invites it to invent a cause and give up. Split the interpretation. `interpret_git_output` treats a zero exit as success even with no stdout; `git_stdout_allow_empty` backs the `Git*` tools; `git_stdout` keeps the non-empty requirement for the one caller where an empty value carries no meaning (`branch --show-current` on a detached HEAD). Successful results now carry an explicit `empty` flag, so "git ran and found nothing" cannot be confused with a failure. Genuine failures name the directory git actually ran in and point at the bash workaround: these tools always use the process working directory and ignore any `cd`, so a workspace root that is not itself a repository is the usual cause and was invisible in the old message. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The read-only
Git*tools reported a successful git invocation as a failure whenever gitprinted nothing, and the failure they reported was specifically "Ensure the current directory is
inside a git repository."
git_stdoutended with(!stdout.is_empty()).then_some(stdout), collapsing two distinct outcomes— git failed, and git succeeded with nothing to say — into the same
None. So a cleanGitDiff,an empty
GitLog, or a blame of an empty file all claimed the repository was missing frominside a perfectly valid one.
That is a bad failure to hand an agent. "You are not in a repository" is a statement about the
environment, not about the query, so the model stops trusting its own working directory and starts
inventing explanations for a machine it cannot see, rather than reading the empty result as
"no changes". Observed in practice: a model received it from a clean staged diff, concluded its
filesystem access was disabled, retried the identical command three times, and ended the task
claiming work was complete that it had never done.
No machine-specific configuration is included — this is code only.
The change
The interpretation is split so the two outcomes stay distinct:
interpret_git_output(success, stdout)— a zero exit is success even with no stdout. Pure,and directly unit-tested.
git_stdout_allow_empty— backs the five read-onlyGit*tools.git_stdout— keeps the non-empty requirement for the one caller where an empty value carriesno meaning:
branch --show-currenton a detached HEAD.Two things also change in what the tools return:
Success payloads carry an explicit
emptyflag.{"output": "", "empty": true}cannot bemisread as a failure, and it cannot be mistaken for a truncated or dropped result either.
Genuine failures name the directory git actually ran in. These tools always use the process
working directory and ignore any
cd—GitDiff'spathis a pathspec after--, not a reposelector — so a workspace root that is not itself a repository is the common cause and was
completely invisible in the old message. The new message names the directory and points at the
cd <repo> && git ...workaround via the bash tool.GitShowandGitBlamekeep their more specific existing error text; only the empty/failuredistinction changes for them.
Verification
cargo test -p tools— 123 pass, 0 fail, including 5 new tests inmod git_output_tests.filter(|s| !s.is_empty())turnstreats_empty_successful_output_as_successred, then restoredgit diff --cached -- <clean path>exits 0 with 0 bytes of stdout, which the old code reported as a missing repository
scripts/fmt.sh --check— cleancargo clippy -p tools --all-targets -- -D warnings— clean for the crate touched. Thepre-existing
crates/runtimelint errors onmainare unchanged by this PRcargo test --workspace— pass/fail counts identical to pristinemainwith these changesreverted; this PR introduces no new failures
🤖 Generated with Claude Code